package utils

import (
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/larspensjo/config"
)

// IsExist - can be used for file and dir
func IsExist(path string) bool {
	_, err := os.Stat(path)
	return err == nil || os.IsExist(err)
	// or
	// return err == nil || !os.IsNotExist(err)
	// or
	// return !os.IsNotExist(err)
}

// LoadConfig - load config from ini
func LoadConfig(conf Config, git Git, fileName string) (*config.Config, error) {
	head, err := git.ThisBranch()
	if err != nil {
		return nil, err
	}
	_, err = git.Execute(
		[]string{"checkout", "sgbm-config"},
		[]string{"pull"},
	)
	if err != nil {
		return nil, err
	}

	var result *config.Config
	result, err = config.ReadDefault(filepath.Join(conf.BasePath, fileName+".ini"))
	if err != nil {
		return nil, err
	}

	_, err = git.Execute(
		[]string{"checkout", head},
	)
	if err != nil {
		return nil, err
	}

	return result, nil
}

// ChangeConfig - change config
type ChangeConfig func(*config.Config) *config.Config

// SaveConfig - save config to ini
func SaveConfig(conf Config, git Git, fileName string, changeConfig ChangeConfig) error {
	head, err := git.ThisBranch()
	if err != nil {
		return err
	}
	_, err = git.Execute(
		[]string{"checkout", "sgbm-config"},
		[]string{"pull"},
	)

	err = changeConfig(config.New(config.DEFAULT_COMMENT,
		config.ALTERNATIVE_SEPARATOR,
		true,
		true)).WriteFile(filepath.Join(conf.BasePath, fileName+".ini"), 0777, fileName+" INFO")
	if err != nil {
		// fmt.Println(err)
		return err
	}

	_, err = git.Execute(
		[]string{"add", "."},
		[]string{"commit", "-m", "save config"},
		[]string{"push", "-u", "origin", "sgbm-config"},
		[]string{"checkout", head},
	)
	if err != nil {
		return err
	}

	return nil
}

// AddConfig - add config to ini
func AddConfig(conf Config, git Git, fileName string, changeConfig ChangeConfig) error {
	head, err := git.ThisBranch()
	if err != nil {
		return err
	}
	_, err = git.Execute(
		[]string{"checkout", "sgbm-config"},
		[]string{"pull"},
	)
	if err != nil {
		return err
	}

	var result *config.Config
	result, err = config.Read(filepath.Join(conf.BasePath, fileName+".ini"),
		config.DEFAULT_COMMENT,
		config.ALTERNATIVE_SEPARATOR,
		true,
		true)
	if err != nil {
		return err
	}
	err = changeConfig(result).WriteFile(filepath.Join(conf.BasePath, fileName+".ini"), 0777, fileName+" INFO")
	if err != nil {
		return err
	}

	_, err = git.Execute(
		[]string{"add", "."},
		[]string{"commit", "-m", "add config"},
		[]string{"push"},
		[]string{"checkout", head},
	)
	if err != nil {
		return err
	}

	return nil
}

func updateVersion(ver string) (string, error) {
	num, err := strconv.Atoi(ver)
	if err != nil {
		return "X", err
	}
	return strconv.Itoa(num + 1), nil
}

// UpdateVersionSmall - 0.0.1 to 0.0.2
func UpdateVersionSmall(ver string) (string, error) {
	temp := strings.Split(ver, ".")
	t, err := updateVersion(temp[2])
	return temp[0] + "." + temp[1] + "." + t, err
}

// UpdateVersionMiddle - 0.0.1 to 0.1.0
func UpdateVersionMiddle(ver string) (string, error) {
	temp := strings.Split(ver, ".")
	t, err := updateVersion(temp[1])
	return temp[0] + "." + t + ".0", err
}

// UpdateVersionLarge - 0.0.1 to 1.0.0
func UpdateVersionLarge(ver string) (string, error) {
	temp := strings.Split(ver, ".")
	t, err := updateVersion(temp[0])
	return t + ".0.0", err
}
